iT邦幫忙

2022 iThome 鐵人賽

DAY 11
0
Web 3

當 APP develop 遇上 web3 與 Metaverse 浪潮 系列 第 11

[Day 拾壹] 如何導入 3D 模型 - 1 常見做法

  • 分享至 

  • xImage
  •  

直接載入

藉由 React.Suspense 延遲載入
再使用 primitive 簡化模型使用


function _GltfScene() {
  const gltf = useLoader(GLTFLoader, 'https://modelviewer.dev/shared-assets/models/NeilArmstrong.glb')
  return (
    <Suspense fallback={null} scale={1}>
      <primitive object={gltf.scene} />
    </Suspense>
  )
}

直接載入 藉由Clone

由於 OpenGl 不能直接使用兩個一模一樣的 模型(mesh)
copy()簡單的說就是複制一個對象的屬性值賦值給給另一個對像對應的屬性。
clone()是相當於新建一個對象,然後復制原對象的屬性值賦值給新的對像對應屬性,也就是說通過克隆方法.clone()創建一個和原來對象完全一樣的對象。


function _GltfScene() {
  const gltf = useLoader(GLTFLoader, 'https://modelviewer.dev/shared-assets/models/NeilArmstrong.glb')
  const { nodes, materials } = gltf
  const { scene } = useThree()

  const cloneScene = gltf.scene.clone()
  return (
    <Suspense fallback={null} scale={1}>
      <Clone>
        <primitive object={cloneScene} />
      </Clone>
    </Suspense>
  )
}

useGLTF()

載入後只使用 {mesh} ,重新添加

function Ruby(props) {
  const { nodes } = useGLTF('https://vazxmixjsiawhamofees.supabase.co/storage/v1/object/public/models/ruby/model.gltf')
  return (
    <mesh geometry={nodes.Ruby.geometry} dispose={null} {...props}>
      <meshPhysicalMaterial clearcoat={1} clearcoatRoughness={0} color="red" transmission={1} thickness={2} roughness={0} />
    </mesh>
  )
}

useGLTF()

載入後分別讀取使用 {mesh,material}

function Duck(props) {
  const { nodes, materials } = useGLTF('https://vazxmixjsiawhamofees.supabase.co/storage/v1/object/public/models/duck/model.gltf')
  return (
    <group {...props} dispose={null}>
      <mesh geometry={nodes.character_duck.geometry} material={nodes.character_duck.material} rotation={[Math.PI / 2, 0, 0]}>
        <mesh geometry={nodes.character_duckArmLeft.geometry} material={nodes.character_duckArmLeft.material} position={[0.2, 0, -0.63]} />
        <mesh geometry={nodes.character_duckArmRight.geometry} material={nodes.character_duckArmRight.material} position={[-0.2, 0, -0.63]} />
        <group position={[0, 0, -0.7]}>
          <mesh geometry={nodes.Cube1338.geometry} material={nodes.Cube1338.material} />
          <mesh geometry={nodes.Cube1338_1.geometry} material={materials['Yellow.043']} />
          <mesh geometry={nodes.Cube1338_2.geometry} material={materials['Black.027']} />
        </group>
      </mesh>
    </group>
  )
}

useGLTF()

載入後分別讀取使用 {mesh,material},再 material 添加新的效果

function Suzi(props) {
  const { scene, materials } = useGLTF('/blender-threejs-journey-20k-transformed.glb')
  // const { scene, materials } = useGLTF('https://market-assets.fra1.cdn.digitaloceanspaces.com/market-assets/models/suzanne-high-poly/model.gltf')
  useLayoutEffect(() => {
    scene.traverse((obj) => obj.isMesh && (obj.receiveShadow = obj.castShadow = true))
    applyProps(materials.boxBase, {
      color: 'black',
      roughness: 0,
      normalMap: new THREE.CanvasTexture(new FlakesTexture(), THREE.UVMapping, THREE.RepeatWrapping, THREE.RepeatWrapping),
      'normalMap-repeat': [40, 40],
      normalScale: [0.05, 0.05]
    })
  })
  return <primitive object={scene} {...props} />
}

drei

/*
Auto-generated by: https://github.com/pmndrs/gltfjsx
*/

import React, { useRef } from 'react'
import { useGLTF } from '@react-three/drei'

export default function Model(props) {
  const { nodes, materials } = useGLTF('/modelCMD.gltf')
  return (
    <group {...props} dispose={null}>
      <ambientLight intensity={0.1} />
      <mesh geometry={nodes.Cube.geometry} material={materials['Material.007']} position={[0.02, 0, 0]} scale={[0.45, 1, 1]} />
      <group scale={[1.1, 1, 1]}>
        <mesh geometry={nodes.立方體.geometry} material={materials['Material.001']} position={[-0.07, 0, 0.47]} scale={[0.1, 1.01, 0.01]} />
        <mesh
          geometry={nodes.立方體001.geometry}
          material={materials['Material.001']}
          position={[-0.07, -0.28, 0.6]}
          rotation={[Math.PI / 2, 0, 0]}
          scale={[0.1, 0.13, 0.02]}
        />
      </group>
      <group position={[-0.06, 0, -0.01]} scale={[0.8, 1.01, 1.02]}>
        <mesh geometry={nodes.Cube001_1.geometry} material={materials['Material.001']} />
        <mesh geometry={nodes.Cube001_2.geometry} material={materials['Material.002']} />
        <mesh geometry={nodes.Cube001_3.geometry} material={materials['Material.003']} />
        <mesh geometry={nodes.Cube001_4.geometry} material={materials['Material.004']} />
        <mesh geometry={nodes.Cube001_5.geometry} material={materials['Material.005']} />
      </group>
    </group>
  )
}

useGLTF.preload('/modelCMD.gltf')


上一篇
[Day 拾] 快速入門 3D 互動網頁
下一篇
[Day 拾貳] 如何導入 3D 模型 - 1 格式轉換
系列文
當 APP develop 遇上 web3 與 Metaverse 浪潮 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言